﻿using DemoApp3.Common;
using DemoApp3.Models;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Security;

namespace DemoApp3
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //load web.config
            AppConfig.Configure();
        }

        public override void Init()
        {
            this.AuthenticateRequest += MvcApplication_AuthenticateRequest;

            base.Init();
        }

        void MvcApplication_AuthenticateRequest(object sender, EventArgs e)
        {
            string requestUrl = HttpContext.Current.Request.RawUrl;

            HttpCookie accessTokenCookie = null;

            if (!new HttpContextWrapper(Context).Request.IsAjaxRequest())
            {
                accessTokenCookie = HttpContext.Current.Request.Cookies[AppConfig.AccessTokenCookieName];
            }
            else
            {
                accessTokenCookie = HttpContext.Current.Request.Cookies[AppConfig.RefreshedAccessTokenCookieName];
            }

            if (accessTokenCookie != null)
            {
                var decryptedAccessTokenTicket = FormsAuthentication.Decrypt(accessTokenCookie.Value);

                if (decryptedAccessTokenTicket != null)
                {
                    string accessToken = decryptedAccessTokenTicket.UserData;

                    // Call authentication API to get User Data
                    RestClientHelp restClientHelp = new RestClientHelp(AppConfig.AuthorizationServerBaseAddress, AppConfig.ResourceServerAPIAddress);
                    string result = restClientHelp.GetUserData(accessToken);

                    if (!string.IsNullOrEmpty(result) && string.Compare(result, "null", true) != 0)
                    {
                        dynamic user = JObject.Parse(result);

                        string userName = user.Name;
                        string userRoles = user.RoleNames;
                        string[] roles = userRoles.Split(',');

                        // If Ajax request, validate if AccessToken is same User with authentication cookie
                        //if (new HttpContextWrapper(Context).Request.IsAjaxRequest())
                        //{
                        //    string authenticatedUserName = HttpContext.Current.Request.Headers.Get(AppConfig.HeaderNameForAjaxAuth);
                        //    userName = string.Compare(userName, authenticatedUserName, true) == 0 ? userName : null;
                        //}

                        // Set current use Identity
                        if (!string.IsNullOrEmpty(userName))
                        {
                            var claims = new List<Claim>();
                            claims.Add(new Claim(ClaimTypes.Name, userName));

                            var identity = new ClaimsIdentity(claims, AppConfig.ClientId + "_FormAuthentication");
                            ClaimsPrincipal principal = new GenericPrincipal(identity, roles);
                            HttpContext.Current.User = principal;
                        }
                    }

                    // If not Ajax request, remove the AccessToken cookie
                    if (!new HttpContextWrapper(Context).Request.IsAjaxRequest())
                    {
                        accessTokenCookie.Expires = DateTime.Now.AddDays(-1);
                        HttpContext.Current.Response.Cookies.Add(accessTokenCookie);
                    }
                }
            }
        }
    }
}
